package SystemeB;

import java.io.PipedReader;
import java.io.PipedWriter;
import java.util.TreeMap;

/**************************************************************************************
 ** Class name: SortFilter 
 *	Original author: Roslane Moussouni, XXX, XXX
 *	CMU Date: 17/01/2011
 * 	Version 1.0
 ** 
 *************************************************************************************** 
 ** Purpose: Assignment 1 for LOG430, Architecture logicielle. This assignment is
 * designed to illustrate a pipe and filter architecture. For the instructions,
 * refer to the assignment write-up.
 ** 
 ** Abstract: This class is intended to be a filter that will collect the streams
 * from two input pipes and merge them into one output pipe..
 ** 
 ** Pseudo Code:
 ** 
 ** connect to input pipe 1 connect to input pipe 2 connect to output pipe
 ** 
 ** while not done read char1 from input pipe 1 read char2 from input pipe 2
 * string1 = string1 + char1 string2 = string2 + char2 write string1 to output
 * pipe write string2 to output pipe end while
 ** 
 ** close pipes close file
 ** 
 ** Running the program
 ** 
 ** See MainFilter.java
 ** 
 ** Modification Log
 ************************************************************************************** 
 ** 
 **************************************************************************************/

public class SortFilter extends Thread {
	// Declarations

	// Create local pipes to that will connect to upstream filters
	PipedReader InputPipe1 = new PipedReader();

	// Create local pipes to that will connect to downstream filter
	PipedWriter OutputPipe1 = new PipedWriter();

	public SortFilter(PipedWriter InputPipe1, PipedWriter OutputPipe1) {
		try {
			// Connect InputPipes to upstream filters
			this.InputPipe1.connect(InputPipe1);
			System.out.println("SortFilter:: connected to upstream filters.");
		} catch (Exception Error) {
			System.out.println("SortFilter:: Error connecting input pipes.");
		} // try/catch

		try {
			// Connect OutputPipe1 to downstream filter
			this.OutputPipe1 = OutputPipe1;
			System.out.println("SortFilter:: connected to downstream filter.");
		} catch (Exception Error) {
			System.out.println("SortFilter:: Error connecting output pipe.");
		} // catch

	} // Constructor

	// This is the method that is called when the thread is started in
	// MainFilter

	public void run() {
		// Declarations
		boolean Done1; // Flags for reading from each pipe

		// Begin process data from the input pipes
		try {
			// Declarations

			// La liste triable
			TreeMap<String,String> bufferList = new TreeMap<String,String>();

			// Need to be an array for easy conversion to string
			char[] CharacterValue1 = new char[1];

			// Indicate when you are done reading on pipes #1 and #2
			Done1 = false;

			// integer values read from the pipes
			int IntegerCharacter1;

			// lines of text from input pipes #1 and #2
			String LineOfText1 = "";

			// Main loop for reading data

			while (!Done1) {
				IntegerCharacter1 = InputPipe1.read();
				CharacterValue1[0] = (char) IntegerCharacter1;

				if (IntegerCharacter1 == -1) // pipe #1 is closed
				{
					Done1 = true;
					System.out.println("SortFilter:: Input pipe 1 closed.");

					try {
						InputPipe1.close();
					} catch (Exception Error) {
						System.out
								.println("SortFilter:: Error closing input pipe 1.");
					} // try/catch

				} else {

					if (IntegerCharacter1 == '\n') // end of line
					{
						System.out.println("SortFilter:: Received: "
								+ LineOfText1 + " on input pipe 1.");

						String object_key = LineOfText1.split(" ")[1];
						String object_value = LineOfText1;
						bufferList.put(object_key, object_value);

						LineOfText1 = "";
					} else {
						LineOfText1 += new String(CharacterValue1);
					} // if

				} // if ( IntegerCharacter1 == -1 )

			} // while ( !Done1)

			// Write the list
			for (String value : bufferList.values()) {
				try {

					System.out.println("SortFilter:: Sending " + value
							+ " to output pipe.");
					String dataToWrite = value += "\n";
					OutputPipe1.write(dataToWrite, 0, dataToWrite.length());
					OutputPipe1.flush();
				} catch (Exception IOError) {
					System.out.println("SortFilter:: Write Error.");
				} // try/catch
			}

		} // try

		catch (Exception Error) {
			System.out.println("SortFilter:: Interrupted.");
		} // catch

		try {
			System.out.println("SortFilter:: output pipe closed.");
			OutputPipe1.close();
		} catch (Exception Error) {
			System.out.println("SortFilter:: Error closing pipes");
		} // try/catch

	} // run

} // class
